CREATE TABLE #Trans 
    (ID INT IDENTITY(10001,1), Amount MONEY, [Sign] CHAR(1))

INSERT INTO #Trans (Amount)
          SELECT 27.87 
UNION ALL SELECT 465.23
UNION ALL SELECT 100.44 
UNION ALL SELECT 23.99 
UNION ALL SELECT 156.55 
UNION ALL SELECT 234.32
UNION ALL SELECT 322.11
UNION ALL SELECT 59.99 
UNION ALL SELECT 184.42
UNION ALL SELECT 201.74
 
SELECT SUM(Amount) FROM #Trans

DECLARE @ReferenceTotal MONEY = 1592.24
    ,@Delimiter CHAR(1) = ','
    ,@ActualTotal MONEY = (SELECT SUM(Amount)FROM #Trans)

DECLARE @AmountOfInterest MONEY = @ActualTotal - @ReferenceTotal

-- Problem #1: Identify potentially double counted transactions
-- Solution #1a: Use UNIQUEnTuples to enumerate the combinatons and
--               keep only those that qualify
;WITH UNIQUEnTuples (n, Tuples, ID, Amount) AS (
    SELECT 1, CAST(ID AS VARCHAR(8000)), ID, Amount
    FROM #Trans
    WHERE Amount <= @AmountOfInterest
    UNION ALL
    SELECT 1 + n.n, CAST(t.ID AS VARCHAR(8000)) + @Delimiter + n.Tuples
        ,t.ID, t.Amount + n.Amount
    FROM UNIQUEnTuples n 
    CROSS APPLY (SELECT t.ID, Amount FROM #Trans t WHERE t.ID < n.ID) t
    WHERE t.Amount + n.Amount <= @AmountOfInterest
    )
SELECT n, [Double Counted Tuples]=Tuples, Amount
FROM UNIQUEnTuples
WHERE Amount = @AmountOfInterest

-- Problem #2: Identify transaction subsets that sum to a specified reference total
-- Solution #2-Step1: Using the same approach to identifying double counted
--             transactions and put these results into a temp table (using
--             ROW_NUMBER() to uniquely identify each solution
;WITH UNIQUEnTuples (n, Tuples, ID, Amount) AS (
    SELECT 1, CAST(ID AS VARCHAR(8000)), ID, Amount
    FROM #Trans
    WHERE Amount <= @AmountOfInterest
    UNION ALL
    SELECT 1 + n.n, CAST(t.ID AS VARCHAR(8000)) + @Delimiter + n.Tuples
        ,t.ID, t.Amount + n.Amount
    FROM UNIQUEnTuples n 
    CROSS APPLY (SELECT t.ID, Amount FROM #Trans t WHERE t.ID < n.ID) t
    WHERE t.Amount + n.Amount <= @AmountOfInterest
    )
SELECT [Soln No]=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    ,[Double Counted Tuples]=Tuples, Amount
INTO #Temp
FROM UNIQUEnTuples
WHERE Amount = @AmountOfInterest

-- Problem #2: Identify transaction subsets that sum to a specified reference total
-- Solution #2-Step2: Eliminate the potentially double counted transactions for
--             each identified solution from the original transaction set
--             and then group the remaining (included) transactions
;WITH MyTrans AS (
    SELECT [Soln No], ID
    FROM #Temp
    CROSS APPLY #Trans
    EXCEPT
    SELECT [Soln No], Item
    FROM #Temp
    CROSS APPLY dbo.DelimitedSplit8K([Double Counted Tuples], @Delimiter)
    )
SELECT [Soln No]
    ,IncludedIDs=STUFF((
        SELECT ',' + CAST(ID AS VARCHAR(10))
        FROM MyTrans b
        WHERE a.[Soln No] = b.[Soln No]
        ORDER BY ID
        FOR XML PATH('')), 1, 1, '')
FROM MyTrans a
GROUP BY [Soln No]

DROP TABLE #Temp

-- Problem #1: Identify potentially double counted transactions
-- Solution #1b: Alternate solution for double counting adhoc analysis
--               using n UNIONed SELECTs, one for each Tuple
SELECT n=1, [Double Counted Tuples]=CAST(ID AS VARCHAR(8000))
    ,Amount
FROM #Trans
WHERE Amount = @AmountOfInterest
UNION ALL
-- Now add in the doublets
SELECT n=2
    ,CAST(a.ID AS VARCHAR(8000)) + ',' + CAST(b.ID AS VARCHAR(8000))
    ,Amount=a.Amount + b.Amount 
FROM #Trans a
INNER JOIN #Trans b ON a.ID < b.ID 
WHERE a.Amount + b.Amount = @AmountOfInterest
UNION ALL
-- And finally the triplets
SELECT n=3
    ,CAST(a.ID AS VARCHAR(8000)) + ',' + CAST(b.ID AS VARCHAR(8000)) + ',' + 
        CAST(c.ID AS VARCHAR(8000))
    ,Amount=a.Amount + b.Amount + c.Amount
FROM #Trans a
INNER JOIN #Trans b ON a.ID < b.ID
INNER JOIN #Trans c ON b.ID < c.ID
WHERE a.Amount + b.Amount + c.Amount = @AmountOfInterest

-- Problem #1: Identify potentially double counted transactions
-- Solution #1c: Alternate solution for double counting adhoc analysis
--               using n UNIONed CROSS APPLYs, one for each Tuple
SELECT n=1, [Double Counted Tuples]=CAST(ID AS VARCHAR(8000))
    ,Amount
FROM #Trans
WHERE Amount = @AmountOfInterest
UNION ALL
-- Now add in the doublets
SELECT n=2
    ,CAST(a.ID AS VARCHAR(8000)) + ',' + CAST(b.ID AS VARCHAR(8000))
    ,Amount=a.Amount + b.Amount 
FROM #Trans a
CROSS APPLY (
    SELECT ID, Amount FROM #Trans b WHERE a.ID < b.ID) b 
WHERE a.Amount + b.Amount = @AmountOfInterest
UNION ALL
-- And finally the triplets
SELECT n=3
    ,CAST(a.ID AS VARCHAR(8000)) + ',' + CAST(b.ID AS VARCHAR(8000)) + ',' + 
        CAST(c.ID AS VARCHAR(8000))
    ,Amount=a.Amount + b.Amount + c.Amount
FROM #Trans a
CROSS APPLY (SELECT ID, Amount FROM #Trans b WHERE a.ID < b.ID) b 
CROSS APPLY (SELECT ID, Amount FROM #Trans c WHERE b.ID < c.ID) c 
WHERE a.Amount + b.Amount + c.Amount = @AmountOfInterest

DECLARE @RowCount INT, @n INT = 1
CREATE TABLE #Temp2 (n INT, Tuples VARCHAR(8000), Amount MONEY, ID INT)

-- Generate first result set (equivalent to anchor leg) into temp table
INSERT INTO #Temp2
SELECT @n, CAST(ID AS VARCHAR(8000)), Amount, ID
FROM #Trans
WHERE Amount <= @AmountOfInterest
SELECT @RowCount = @@ROWCOUNT

-- WHILE loop simulates recursive leg of the rCTE
WHILE @RowCount <> 0
BEGIN
    SELECT @n = @n + 1

    INSERT INTO #Temp2
    SELECT @n
        ,CAST(a.ID AS VARCHAR(8000)) + ',' + Tuples
        ,Amount=a.Amount + b.Amount 
        ,a.ID
    FROM #Trans a
    INNER JOIN #Temp2 b ON b.n = @n - 1 AND 
        a.ID < b.ID AND
        a.Amount + b.Amount <= @AmountOfInterest

    SELECT @RowCount = @@ROWCOUNT 
END

-- Finally SELECT out based on the amount of interest
SELECT n, [Double Counted Tuples]=Tuples, Amount
FROM #Temp2
WHERE Amount = @AmountOfInterest

DROP TABLE #Temp2

TRUNCATE TABLE #Trans

INSERT INTO #Trans (Amount, [Sign])
          SELECT 100, '+'       -- [Assigned ID is 10001]
UNION ALL SELECT -100, '+'      -- [Assigned ID is 10002]
UNION ALL SELECT 200, '-'       -- [Assigned ID is 10003]
UNION ALL SELECT -200, '-'      -- [Assigned ID is 10004]
UNION ALL SELECT 300, '-'       -- [Assigned ID is 10005]
UNION ALL SELECT -300, '+'      -- [Assigned ID is 10006]
UNION ALL SELECT 400, '+'       -- [Assigned ID is 10007]
UNION ALL SELECT -400, '-'      -- [Assigned ID is 10008]
UNION ALL SELECT 800, '+'       -- [Assigned ID is 10009]
UNION ALL SELECT -800, '-'      -- [Assigned ID is 10010]

SELECT * FROM #Trans

SELECT SUM(CASE [Sign] WHEN '+' THEN Amount ELSE -Amount END)
FROM #Trans

SELECT @ReferenceTotal = 2400
    ,@ActualTotal = SUM(CASE [Sign] WHEN '+' THEN Amount ELSE -Amount END)
FROM #Trans

-- Problem #3: Identify transactions with reversed signs
-- Solution #3: Create the Tuples based on subtracting 2* the amount from
--              the actual total.
;WITH UNIQUEnTuples (n, Tuples, ID, Total) AS (
    SELECT 1, CAST(ID AS VARCHAR(8000)), ID
        ,@ActualTotal - 2 * CASE [Sign] WHEN '+' THEN Amount ELSE -Amount END
    FROM #Trans
    UNION ALL
    SELECT 1 + n.n, CAST(t.ID AS VARCHAR(8000)) + ',' + n.Tuples, t.ID
        ,n.Total - 2 * CASE [Sign] WHEN '+' THEN t.Amount ELSE -t.Amount END
    FROM UNIQUEnTuples n 
    CROSS APPLY (
        SELECT ID, Amount, [Sign] 
        FROM #Trans t 
        WHERE t.ID < n.ID) t
    -- Limit the recursion depth (to 3-Tuples)
    WHERE n < 3
    )
SELECT n, [Reversed Sign Tuples]=Tuples, Total
FROM UNIQUEnTuples
WHERE Total = @ReferenceTotal


DROP TABLE #Trans